﻿
Imports System.Text
Imports std

Public Module interspace
    Public Delegate Function convert_d(Of IT, OT)(ByVal i As IT, ByRef o As OT) As Boolean

    Public Function bytes_to_int64(ByVal i As bytes, ByRef o As Int64) As Boolean
        Return convertor.toint64(i, o)
    End Function

    Public Function int64_to_bytes(ByVal i As Int64, ByRef o As bytes) As Boolean
        Return convertor.tobytes(i, o)
    End Function

    Public Function bytes_to_string(ByVal i As bytes, ByRef o As String) As Boolean
        If i Is Nothing Then
            Return False
        Else
            o = encoding.utf8().GetString(+i)
            Return True
        End If
    End Function

    Public Function string_to_bytes(ByVal i As String, ByRef o As bytes) As Boolean
        If i Is Nothing Then
            Return False
        Else
            o = New bytes(encoding.utf8().GetBytes(i))
            Return True
        End If
    End Function

    Private Delegate Sub insert_d(Of T)(ByVal i As T)

    Private Function bytes_to_int64s(ByVal i As bytes, ByVal insert As insert_d(Of Int64)) As Boolean
        assert(Not insert Is Nothing)
        Dim args() As bytesInt64 = Nothing
        If deserialize(i, args) Then
            assert(Not args Is Nothing)
            For j As Int64 = 0 To args.Length() - 1
                insert(+args(j))
            Next
            Return True
        Else
            Return False
        End If
    End Function

    Private Function int64s_to_bytes(ByVal get_next As _do(Of Int64, Boolean), ByRef o As bytes) As Boolean
        assert(Not get_next Is Nothing)
        Dim v As vector(Of bytesInt64) = Nothing
        v = New vector(Of bytesInt64)()
        Dim i As Int64 = 0
        While get_next(i)
            assert(v.push_back(New bytesInt64(i)))
        End While
        Return serialize(o, +v)
    End Function

    Public Function bytes_to_vector_int64(ByVal i As bytes, ByRef o As vector(Of Int64)) As Boolean
        o = New vector(Of Int64)()
        Return bytes_to_int64s(i, AddressOf o.push_back)
    End Function

    Public Function vector_int64_to_bytes(ByVal i As vector(Of Int64), ByRef o As bytes) As Boolean
        If i Is Nothing Then
            Return False
        Else
            Return int64s_to_bytes(get_next(i), o)
        End If
    End Function

    Public Function bytes_to_set_int64(ByVal i As bytes, ByRef o As [set](Of Int64)) As Boolean
        o = New [set](Of Int64)()
        Return bytes_to_int64s(i, AddressOf o.insert)
    End Function

    Public Function set_int64_to_bytes(ByVal i As [set](Of Int64), ByRef o As bytes) As Boolean
        If i Is Nothing Then
            Return False
        Else
            Return int64s_to_bytes(get_next(i), o)
        End If
    End Function

    Private Function string_to_strings(ByVal i As String,
                                       ByVal insert As insert_d(Of String),
                                       ByVal separator As String,
                                       ByVal ignore_empty_entities As Boolean) As Boolean
        If i Is Nothing Then
            Return False
        Else
            assert(Not insert Is Nothing)
            strsepar2(Of Byte)(i, separator, 0, Sub(x, y) insert(y), ignore_empty_entities)
            Return True
        End If
    End Function

    Private Function strings_to_string(ByVal get_next As _do(Of String, Boolean),
                                       ByVal separator As String,
                                       ByVal ignore_empty_entities As Boolean,
                                       ByRef o As String) As Boolean
        assert(Not get_next Is Nothing)
        Dim s As String = Nothing
        Dim sb As StringBuilder = Nothing
        sb = New StringBuilder()
        While get_next(s)
            If Not isemptystring(o) Then
                sb.Append(separator)
            End If
            If Not (ignore_empty_entities AndAlso isemptystring(s)) Then
                sb.Append(s)
            End If
        End While

        o = Convert.ToString(o)
        Return True
    End Function

    Public Function string_to_vector_string(ByVal i As String,
                                            ByRef o As vector(Of String),
                                            ByVal separator As String,
                                            ByVal ignore_empty_entites As Boolean) As Boolean
        o = New vector(Of String)()
        Return string_to_strings(i, AddressOf o.push_back, separator, ignore_empty_entites)
    End Function

    Public Function vector_string_to_string(ByVal i As vector(Of String),
                                            ByRef o As String,
                                            ByVal separator As String,
                                            ByVal ignore_empty_entities As Boolean) As Boolean
        If i Is Nothing Then
            Return False
        Else
            Return strings_to_string(get_next(i), separator, ignore_empty_entities, o)
        End If
    End Function

    Public Function bytes_to_vector_string(ByVal i As bytes,
                                           ByRef o As vector(Of String),
                                           ByVal separator As String,
                                           ByVal ignore_empty_entities As Boolean) As Boolean
        Dim s As String = Nothing
        Return bytes_to_string(i, s) AndAlso string_to_vector_string(s, o, separator, ignore_empty_entities)
    End Function

    Public Function vector_string_to_bytes(ByVal i As vector(Of String),
                                           ByRef o As bytes,
                                           ByVal separator As String,
                                           ByVal ignore_empty_entities As Boolean) As Boolean
        Dim s As String = Nothing
        Return vector_string_to_string(i, s, separator, ignore_empty_entities) AndAlso string_to_bytes(s, o)
    End Function

    Public Function string_to_set_string(ByVal i As String,
                                         ByRef o As [set](Of String),
                                         ByVal separator As String,
                                         ByVal ignore_empty_entities As Boolean) As Boolean
        o = New [set](Of String)()
        Return string_to_strings(i, AddressOf o.insert, separator, ignore_empty_entities)
    End Function

    Public Function set_string_to_string(ByVal i As [set](Of String),
                                         ByRef o As String,
                                         ByVal separator As String,
                                         ByVal ignore_empty_entities As Boolean) As Boolean
        If i Is Nothing Then
            Return False
        Else
            Return strings_to_string(get_next(i), separator, ignore_empty_entities, o)
        End If
    End Function

    Public Function bytes_to_set_string(ByVal i As bytes,
                                        ByRef o As [set](Of String),
                                        ByVal separator As String,
                                        ByVal ignore_empty_entities As Boolean) As Boolean
        Dim s As String = Nothing
        Return bytes_to_string(i, s) AndAlso string_to_set_string(s, o, separator, ignore_empty_entities)
    End Function

    Public Function set_string_to_bytes(ByVal i As [set](Of String),
                                        ByRef o As bytes,
                                        ByVal separator As String,
                                        ByVal ignore_empty_entities As Boolean) As Boolean
        Dim s As String = Nothing
        Return set_string_to_string(i, s, separator, ignore_empty_entities) AndAlso string_to_bytes(s, o)
    End Function
End Module
